#include "GowildDevice.h"

GowildDevice::GowildDevice(QObject *parent) :
    BaseInterface<GowildDevice>(parent)
{
    m_pInstance = this;
  qDebug()<<"GowildDevice runing-1";
    m_deviceTypeHash.insert("开关","SIMPLE_DEVICE");
    m_deviceTypeHash.insert("灯光","LIGHT");
    m_deviceTypeHash.insert("窗帘","CURTAIN");
    m_deviceTypeHash.insert("窗纱","VOILE_CURTAIN");
    m_deviceTypeHash.insert("空调","AIR_CONDITION");
    m_deviceTypeHash.insert("新风","ELECTRIC_FAN");
    m_deviceTypeHash.insert("地暖","FLOOR_WARM");
    m_deviceTypeHash.insert("音乐","MUSIC");

    m_stateHash.insert("STATE_ON","开");
    m_stateHash.insert("STATE_OFF","关");
    m_stateHash.insert("STATE_STOP","停");

    m_modeHash.insert("MODE_COOL","制冷");
    m_modeHash.insert("MODE_HEAT","制热");
    m_modeHash.insert("MODE_FAN", "送风");
    m_modeHash.insert("MODE_DRY", "除湿");
    m_modeHash.insert("MODE_AUTO","自动");
    m_modeHash.insert("MODE_WIND_HIGH", "高");
    m_modeHash.insert("MODE_WIND_MID", "中");
    m_modeHash.insert("MODE_WIND_LOW","低");
    m_modeHash.insert("MODE_PLAY","播放");
    m_modeHash.insert("MODE_PAUSE", "暂停");
    m_modeHash.insert("MODE_NEXT", "下一曲");
    m_modeHash.insert("MODE_PREVIOUS","上一曲");


    m_attributeHash.insert("ATTRIBUTE_WIND_SPEED","风速");
    m_attributeHash.insert("ATTRIBUTE_TEMPERATURE","温度");
    m_attributeHash.insert("ATTRIBUTE_VOLUME","音量");

    PointIni *pointIni = PointIni::getInstance();
    m_pointHash = pointIni->pointHash();
    m_zoneHash  = pointIni->zoneHash();

    m_roomHash  = this->roomHash();
    m_sceneHash =  this->sceneHash();
    m_deviceHash =  this->deviceHash();

    gowildProtocol = new GowildProtocol(this);
    this->registerProtocol(gowildProtocol);

    registerCmdHandler(GowildSearchCmd::FunctionCode,GowildSearchCmd::staticMetaObject, &GowildDevice::gowildSearchCmdHandle);
    registerCmdHandler(GowildRequestHeartbeatCmd::FunctionCode,GowildRequestHeartbeatCmd::staticMetaObject, &GowildDevice::gowildRequestHeartbeatCmdHandle);
    registerCmdHandler(GowildRequestDeviceListCmd::FunctionCode,GowildRequestDeviceListCmd::staticMetaObject, &GowildDevice::gowildRequestDeviceListCmdHandle);
    registerCmdHandler(GowildRequestSceneListCmd::FunctionCode,GowildRequestSceneListCmd::staticMetaObject, &GowildDevice::gowildRequestSceneListCmdHandle);
    registerCmdHandler(GowildRequestRoomListCmd::FunctionCode,GowildRequestRoomListCmd::staticMetaObject, &GowildDevice::gowildRequestRoomListCmdHandle);
    registerCmdHandler(GowildRequestFloorListCmd::FunctionCode,GowildRequestFloorListCmd::staticMetaObject, &GowildDevice::gowildRequestFloorListCmdHandle);
    registerCmdHandler(GowildControlCmd::FunctionCode,GowildControlCmd::staticMetaObject, &GowildDevice::gowildControlCmdHandle);
    qDebug()<<"GowildDevice runing-2";
}

QHash<int,QString> GowildDevice::roomHash()
{
    QHash<int,QString> roomHash = m_zoneHash;
    return roomHash;
}

QHash<int,Gowild::SceneStruct> GowildDevice::sceneHash()
{

    QHash<int,Gowild::SceneStruct> sceneHash;

    int sceneId = 0;
    QStringList roomList = m_pointHash.keys();
    roomList.removeDuplicates();
    foreach (const QString &room, roomList)
    {
        QList<PointStruct> pointList = m_pointHash.values(room);
        foreach (const PointStruct &point, pointList)
        {
            if(point.deviceType() == "场景")
            {
                QStringList valueNameList = point.valueTable().keys();
                valueNameList.removeDuplicates();
                foreach (const QString &valueName, valueNameList)
                {
                    Gowild::SceneStruct scene;
                    scene.setRoom(point.zoneName());
                    scene.setName(valueName);
                    sceneHash.insert(sceneId++,scene);
                }
            }
        }
    }

    return sceneHash;
}

QHash<int,Gowild::DeviceStruct> GowildDevice::deviceHash()
{
    QHash<int,Gowild::DeviceStruct> deviceHash;

    int deciveId = 0;
    QStringList roomList = m_pointHash.keys();
    roomList.removeDuplicates();
    foreach (const QString &room, roomList)
    {
        QMultiHash<QString,QString>  deviceNameTypeHash;
        QList<PointStruct> pointList = m_pointHash.values(room);
        foreach (const PointStruct &point, pointList)
        {
            QString deviceName;
            QRegExp rx("(.*)-(.*)-(.*)");
            if(rx.exactMatch(point.name()))
            {
                deviceName = rx.cap(2);
            }
            else
            {
                deviceName = point.deviceType() + QString::number(point.deviceIndex(),10);
            }
            if((point.deviceType() !="环境")
                && (point.deviceType() !="PM2.5")
                && (point.deviceType() !="场景"))
            {
                deviceNameTypeHash.insert(deviceName,point.deviceType());
            }
        }
        QStringList deviceNameList = deviceNameTypeHash.keys();
        deviceNameList.removeDuplicates();
        foreach (const QString &deviceName, deviceNameList)
        {
            Gowild::DeviceStruct device;
            device.setName(deviceName);
            device.setType(m_deviceTypeHash.value(deviceNameTypeHash.value(deviceName)));
            device.setRoomId(m_roomHash.key(room));
            deviceHash.insert(deciveId++,device);
        }
    }

    return deviceHash;
}

void GowildDevice::gowildSearchCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(sharedCmd);
    GowildSearchCmd *gowildSearchCmd = new GowildSearchCmd();

    System *system = System::getInstance();
    gowildSearchCmd->setIp(system->ip());
    quint16 portNumber = 0;
    foreach (const BasePort *port , m_portList)
    {
         if(port->portParam().type() == "TCPServer")
         {
             portNumber = port->portParam().port();
         }
    }
    gowildSearchCmd->setPort(portNumber);
    gowildSearchCmd->setCompany("LEWIN");

    QSharedPointer<BaseCmd> sharedGowildSearchCmd(gowildSearchCmd);
    this->sendCmd(source,sharedGowildSearchCmd);
}

void GowildDevice::gowildRequestHeartbeatCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(sharedCmd);
    GowildResponseHeartbeatCmd *gowildResponseHeartbeatCmd = new GowildResponseHeartbeatCmd();

    QSharedPointer<BaseCmd> sharedGowildResponseHeartbeatCmd(gowildResponseHeartbeatCmd);
    this->sendCmd(source,sharedGowildResponseHeartbeatCmd);
}

void GowildDevice::gowildRequestDeviceListCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(sharedCmd);
    GowildResponseDeviceListCmd *gowildResponseDeviceListCmd = new GowildResponseDeviceListCmd;
    gowildResponseDeviceListCmd->setDeviceHash(m_deviceHash);
    QSharedPointer<BaseCmd> sharedGowildResponseDeviceListCmd(gowildResponseDeviceListCmd);
    this->sendCmd(source,sharedGowildResponseDeviceListCmd);
}

void GowildDevice::gowildRequestSceneListCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(sharedCmd);
    GowildResponseSceneListCmd *gowildResponseSceneListCmd = new GowildResponseSceneListCmd;
    gowildResponseSceneListCmd->setSceneHash(m_sceneHash);
    QSharedPointer<BaseCmd> sharedGowildResponseSceneListCmd(gowildResponseSceneListCmd);
    this->sendCmd(source,sharedGowildResponseSceneListCmd);
}

void GowildDevice::gowildRequestRoomListCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(sharedCmd);
    GowildResponseRoomListCmd *gowildResponseRoomListCmd = new GowildResponseRoomListCmd;
    gowildResponseRoomListCmd->setRoomHash(m_roomHash);
    QSharedPointer<BaseCmd> sharedGowildResponseRoomListCmd(gowildResponseRoomListCmd);
    this->sendCmd(source,sharedGowildResponseRoomListCmd);
}

void GowildDevice::gowildRequestFloorListCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(sharedCmd);
    GowildResponseFloorListCmd *gowildResponseFloorListCmd = new GowildResponseFloorListCmd;
    QSharedPointer<BaseCmd> sharedGowildResponseFloorListCmd(gowildResponseFloorListCmd);
    this->sendCmd(source,sharedGowildResponseFloorListCmd);
}

void GowildDevice::gowildControlCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    GowildControlCmd *gowildControlCmd = qobject_cast<GowildControlCmd*>(sharedCmd.data());
    QList<Gowild::ControlParamStruct> controlParamList = gowildControlCmd->controlParamList();
    QList<ControlPointStruct> controlPointList;
    foreach (const Gowild::ControlParamStruct &controlParam, controlParamList)
    {
        int id = controlParam.id();
        QString action = controlParam.action();
        QString attribute = controlParam.attribute();
        QString attributeValue = controlParam.attributeValue();
        QString mode = controlParam.mode();
        QString name = controlParam.name();
        QString room = m_roomHash.value(controlParam.room().toInt());
        QString scene = controlParam.scene();
        QString state = controlParam.state();

        if(!scene.isEmpty())
        {
            room  = m_sceneHash.value(id).room();
            scene = m_sceneHash.value(id).name();
        }
        QList<PointStruct> pointList = m_pointHash.values(room);
        foreach (const PointStruct &point, pointList)
        {
            if(!name.isEmpty() && point.name().contains(name))
            {
                if(!state.isEmpty())
                {
                    bool isExist = point.valueTable().contains(m_stateHash.value(state));
                    if(isExist)
                    {
                        quint16 address = point.address();
                        quint16 value = point.valueTable().value(m_stateHash.value(state));
                        ControlPointStruct controlPoint;
                        controlPoint.setAddress(address);
                        controlPoint.setValue(value);
                        controlPointList.append(controlPoint);
                        break;
                    }
                }

                if(!attribute.isEmpty() && point.funcType().contains(m_attributeHash.value(attribute)) && point.funcType() != "当前温度")
                {
                    QString valueName = attributeValue;
                    if(attribute == "ATTRIBUTE_TEMPERATURE")
                    {
                        valueName = attributeValue + "度";
                    }
                    bool isExist = point.valueTable().contains(valueName);
                    if(isExist)
                    {
                        quint16 address = point.address();
                        quint16 value = point.valueTable().value(valueName);
                        ControlPointStruct controlPoint;
                        controlPoint.setAddress(address);
                        controlPoint.setValue(value);
                        controlPointList.append(controlPoint);
                        break;
                    }

                }

                if(!mode.isEmpty())
                {
                    bool isExist = point.valueTable().contains(m_modeHash.value(mode));
                    if(isExist)
                    {
                        quint16 address = point.address();
                        quint16 value = point.valueTable().value(m_modeHash.value(mode));
                        ControlPointStruct controlPoint;
                        controlPoint.setAddress(address);
                        controlPoint.setValue(value);
                        controlPointList.append(controlPoint);
                        break;
                    }
                }
            }

            if(!scene.isEmpty())
            {
                bool isExist = point.valueTable().contains(scene);
                if(isExist)
                {
                    quint16 address = point.address();
                    quint16 value = point.valueTable().value(scene);
                    ControlPointStruct controlPoint;
                    controlPoint.setAddress(address);
                    controlPoint.setValue(value);
                    controlPointList.append(controlPoint);
                    break;
                }
            }
        }
    }
    if(controlPointList.isEmpty())
    {
        return;
    }

    ControlPointFunc *pointControlFunc = new ControlPointFunc();
    pointControlFunc->setSourceDevice(this->name());
    pointControlFunc->setSourcePointList(controlPointList);
    QSharedPointer<BaseFunc> sharedPointControlFunc(pointControlFunc);
    emit transferFuncSignal(sharedPointControlFunc);


}
